using Gameplay.PVE.Entity;
using Gameplay.PVE.Utils;
using UnityEngine;

namespace Gameplay.PVE
{
    public class SelfRangerMoveBehaviour : SelfMoveBehaviour
    {
        public override void Init(UnitBase unit, UnitRoadPath roadPath)
        {
            base.Init(unit, roadPath);
            if (roadPath is AStarRoadPath path)
            {
                path.SetCondition2Handler(() =>
                {
                    if (unit.Data.isGoingToHidePoint)
                    {
                        var d = Vector3.Distance(unit.Data.attackPosition, unit.Data.position);
                        return d < unit.Data.configMoveSpeed * TimeManager.LogicDeltaTime;
                    }
                    else if (unit.Data.lockTarget == null || unit.Data.lockTarget.Data.isDead)
                    {
                        return false;
                    }
                    return unit.Data.IsAttackInRange(1);
                });
                path.SetForceEndCondition(() => { return unit.Data.isGoingToHidePoint; });
            }
        }

        protected override void UpdateGame()
        {
            base.UpdateGame();
            if (unit.Data.IsInSkill() || unit.Data.isInAction || unit.Data.isHiding)
            {
                if (unit.Data.moveState == 3 || unit.Data.moveState == 4)
                {
                    
                }
                else
                {
                    unit.Data.manualForward = Vector3.zero;
                }
                
                //unit.Data.moveState = -1;
                return;
            }

            if (unit.Data.isGoingToHidePoint)
            {
                DoGoToHidePoint();
            }
            else if (PveGlobalVlues.HitAndRun == 0)
            {
                unit.Data.moveState = 0;
                //移动设计
                if (PveManager.Instance.rpgStart && unit.Data.rpgMoveAttackId > 0)
                {
                    DoRandomWalk();
                    if (unit.Data.isReloading || unit.Data.isInAction || unit.Data.isHiding)
                    {
                        unit.Data.moveState = 0;
                    }
                }
            }
            else
            {
                //hit and run
                if (PveManager.Instance.rpgStart)
                {
                    DoHitAndRun();
                }
            }
        }

        private void DoGoToHidePoint()
        {
            Vector3 targetPosition;
            if (unit.Data.lockTarget == null || unit.Data.lockTarget.Data.isDead)
            {
                targetPosition = unit.Data.targetPosition;
                unit.Data.SetTargetForward(unit.Data.forward);
            }
            else
            {
                if (unit.Data.attackPosition != Vector3.zero)
                {
                    targetPosition = unit.Data.attackPosition;
                   
                    var d = Vector3.Distance(targetPosition, unit.Data.position);
                    if (d <= unit.Data.configMoveSpeed * TimeManager.LogicDeltaTime)
                    {
                        unit.Data.position = targetPosition;
                        unit.Data.attackPosition = targetPosition;
                        unit.Data.moveState = -1;
                        return;
                    }
                    else
                    {
                        unit.Data.moveState = 2;
                        unit.Data.SetTargetPosition(unit.Data.attackPosition);
                    }
                }
                else
                {
                    unit.Data.isGoingToHidePoint = false;
                    var nearestPosition = unit.Data.lockTarget.Data.position + (unit.Data.position - unit.Data.lockTarget.Data.position).normalized * unit.Data.attackRange;
                    if (unit.Data.IsAttackInRange())
                    {
                        targetPosition = unit.Data.position;
                    }
                    else
                    {
                        targetPosition = unit.Data.lockTarget.Data.position;
                    }
                    unit.Data.moveState = 2;
                    unit.Data.SetTargetPosition(unit.Data.attackPosition);
                }
            }
        }
        
        private void DoHitAndRun()
        {
            /*if (unit.Data.IsInAttack())
            {
                unit.Data.attackPosition = Vector3.zero;
                return;
            }*/

            if (unit.Data.attackPosition == Vector3.zero)
            {
                unit.Data.attackPosition = unit.Data.birthPosition +
                                           PveUtils.GetRandomVector3(new Vector3(-1, 0, -1), new Vector3(1, 0, 1));
                
            }

            if (unit.Data.IsInAttack() || unit.Data.isReloading || unit.Data.attackPosition == unit.Data.position)
            {
                unit.Data.moveState = 0;
            }
            else
            {
                unit.Data.moveState = 2;
            }
        }
        
        private BattleUnit hatredUnit;
        
        private float minRegionX = -10;
        private float minRegionY = -5;
        private float maxRegionX = 10f;
        private float maxRegionY = 5;

        private float aiInterval = 1;
        private Vector3 backDirection;
        private float lastAiTime;
        private float xMax;
        private float xMin;
        private float zMax;
        private float zMin;
        private Vector3 walkDestination;
        private int moveState = 0;
        
        private void DoRandomWalk()
        {
            hatredUnit = null;//unit.Data.hatredTarget;
            if (hatredUnit != null && hatredUnit.Data.isDead)
            {
                hatredUnit = null;
            }
            if (moveState == 0 && (unit.Data.IsInAttack() || unit.Data.isReloading))
            {
                moveState = 1;
            }

            if (moveState == 3 && !unit.Data.isMoveAttacking)
            {
                if (hatredUnit != null)
                {
                    moveState = 2;
                }
                else
                {
                    moveState = 0;
                }
            }
            if (moveState == 0)
            {
                unit.Data.manualForward = Vector3.zero;
                unit.Data.moveState = 0;
            }
            else if (moveState == 1 && !unit.Data.IsInAttack())
            {
                if (hatredUnit != null || Random.Range(0, 1f) < 0.3f)
                {
                    moveState = 2;
                }
                else
                {
                    moveState = 0;
                }
                
            }
            else if (moveState == 2 && unit.Data.isMoveAttacking)
            {
                moveState = 3;
            }
           
            if (moveState == 1 || moveState == 2 || moveState == 3)
            {
                if (hatredUnit != null)
                {
                    var forward = unit.Data.position - hatredUnit.Data.position;
                    bool isCanMove = false;
                    if (lastAiTime == 0)
                    {
                        isCanMove = true;
                        lastAiTime = TimeManager.logicTime;
                    }
                    else if (TimeManager.logicTime - lastAiTime < aiInterval * 2)
                    {
                        isCanMove = true;
                    }
                    /*else if (TimeManager.logicTime - lastAiTime < 4 * aiInterval)
                    {
                        isCanMove = false;
                    }*/
                    else
                    {
                        backDirection = Vector3.zero;
                        lastAiTime = 0;
                    }
                    if (isCanMove && forward.sqrMagnitude <= unit.Data.attackRange * unit.Data.attackRange * 0.7f * 0.7f)
                    {
                        if (backDirection == Vector3.zero)
                        {
                            forward = Quaternion.AngleAxis(Random.Range(-30f,30f),Vector3.up) * forward.normalized;
                            backDirection = forward;
                            
                        }
                        
                        var offset = unit.Data.configMoveSpeed * TimeManager.LogicDeltaTime * backDirection.normalized;
                        
                        
                        var x = offset.x + unit.Data.position.x;
                        var z = offset.z + unit.Data.position.z;
                        float angle = 0;

                        zMin = unit.Data.birthPosition.z - 4;
                        zMax = unit.Data.birthPosition.z + 4;
                        xMin = unit.Data.birthPosition.x - 4;
                        xMax = unit.Data.birthPosition.x + 4;
                        //if (PveManager.Instance.mainUnit != null)
                        {
                            var minRegionY = zMin;
                            var maxRegionY = zMax;
                            var minRegionX = xMin;
                            var maxRegionX = xMax;
                            if (z < minRegionY || z > maxRegionY)
                            {
                                offset = offset.x < 0 ? Vector3.left : Vector3.right;
                            }
                            if (x < minRegionX || x > maxRegionX)
                            {
                                offset = offset.z < 0 ? Vector3.back : Vector3.forward;
                            }
                        }
                        
                        angle = PveUtils.GetAngle(backDirection, offset);
                        if (angle != 0)
                        {
                            angle = angle / Mathf.Abs(angle);
                            angle = Random.Range(0, 60 * angle);
                        }
                       
                        backDirection = Quaternion.AngleAxis(angle,Vector3.up) * offset;
                        
                        unit.Data.manualForward =  backDirection.normalized;
                        unit.Data.moveState = moveState == 1 ? 0 : 1;
                    }
                    else
                    {
                        unit.Data.manualForward = Vector3.zero;
                        unit.Data.moveState = 0;
                    }
                }
                else
                {
                    if (walkDestination == Vector3.zero || Vector3.Distance(unit.Data.position, walkDestination) <=
                        unit.Data.walkSpeed * TimeManager.LogicDeltaTime || PveFindPathManager.Instance.CheckIsOutOfBound(unit.Data.position + unit.Data.walkSpeed * Time.deltaTime * unit.Data.manualForward) || !unit.Data.IsInScreen())
                    {
                        //找新的地点
                        float rad = Random.Range(0, 360f) * Mathf.Deg2Rad;
                        float x = Mathf.Cos(rad);
                        float z = Mathf.Sin(rad);
                        float radius = 1f;
                        walkDestination = unit.Data.birthPosition + new Vector3(radius * x, 0, radius * z);
                        if (!PveFindPathManager.Instance.CheckIsWalkable(walkDestination, unit.Data.id) || PveFindPathManager.Instance.CheckIsOutOfBound(walkDestination))
                        {
                            walkDestination = unit.Data.position;
                            moveState = 1;
                        }
                    }
                    else
                    {

                    }

                    unit.Data.manualForward = walkDestination - unit.Data.position;
                    unit.Data.moveState = moveState == 1 ? 0 : 1;
                }
            }
        }
    }
}